#!/usr/bin/env python
# yongming.li 

import sys
import os
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import copy


kmemleakPath = os.path.dirname(__file__)
print 'kmemleakPath is : ' + kmemleakPath
sys.path.append('../'+kmemleakPath)


class KmemleakForm(QDialog):

    def  isscanstack(self,value):
         print value
         if value :
             cmd = 'adb shell "echo stack=on > %s "  '%(self.kmemleak_kernel)
         else:
             cmd = 'adb shell "echo stack=off > %s "  '%(self.kmemleak_kernel)
         print cmd
         os.system(cmd)
         
    def  setscanperiod(self,value):
         print value
         cmd = 'adb shell "echo scan=%d > %s "  '%(value,self.kmemleak_kernel)
         print cmd
         os.system(cmd)
    def  isautoscanmemory(self,value):
         print value
         if value :
             cmd = 'adb shell "echo scan=on > %s "  '%(self.kmemleak_kernel)
         else:
             cmd = 'adb shell "echo scan=off > %s "  '%(self.kmemleak_kernel)
         print cmd
         os.system(cmd)

    def  showresults(self,name):
        self.resultgbox = QtGui.QGroupBox(name)
        layout = QtGui.QGridLayout()
        self.resultedit = QtGui.QTextEdit('')
        self.resultedit.setTextColor(QColor(255, 0, 0, 255))

        layout.addWidget(self.resultedit,0,0)
        self.resultgbox.show()
        self.resultgbox.setLayout(layout)

    def  kmemleakclear(self):
        print 'clear'
        cmd = 'adb shell "echo clear > %s "  '%(self.kmemleak_kernel)
        print cmd
        os.system(cmd)
        
    def  kmemleakbegin(self):
        #print 'begin'
        cmd = 'adb shell "echo scan > %s  "  '%(self.kmemleak_kernel)
        print cmd
        os.system(cmd)
        cmd = 'adb shell "cat  %s "  '%(self.kmemleak_kernel)
        lines = os.popen(cmd).readlines()
        self.resultedit.clear()
        for  line  in lines: 
            line = line.strip()
            if len(line) == 0 :
                continue
            self.resultedit.append(line)

    def  showcontrol(self,name):
        self.controlgbox = QtGui.QGroupBox(name)
        layout = QtGui.QGridLayout()
       
        #layout = QtGui.QVBoxLayout()

        self.clearbutton = QPushButton(' clear ')
        self.beginbutton = QPushButton(' begin scan ')
        layout.addWidget(self.clearbutton,0,0)
        layout.addWidget(self.beginbutton,0,1)

        self.connect(self.clearbutton, SIGNAL('clicked()'), self.kmemleakclear)
        self.connect(self.beginbutton, SIGNAL('clicked()'), self.kmemleakbegin)

        #layout.addStretch(3)
        self.controlgbox.show()
        self.controlgbox.setLayout(layout)

    def  showkmemleakoptions(self,name):
        self.optionsgbox = QtGui.QGroupBox(name)
        layout = QtGui.QGridLayout()
 
        self.scanperiodLabel = QtGui.QLabel("scanning period in seconds:")

        self.scanperiodSpinBox = QtGui.QSpinBox()
        self.scanperiodSpinBox.setRange(0, 1000)
        self.scanperiodSpinBox.setSingleStep(10)
        self.scanperiodSpinBox.setValue(600)

        self.isscanstackCheckBox = QtGui.QCheckBox("enable stacks scanning ")
        self.isscanstackCheckBox.toggled.connect(self.isscanstack)

        self.isautoscanCheckBox = QtGui.QCheckBox("automatic memory scanning ")
        self.isautoscanCheckBox.toggled.connect(self.isautoscanmemory)

        

        self.scanperiodSpinBox.valueChanged.connect(self.setscanperiod)

        btn = QtGui.QPushButton('------------------------------')


        layout.addWidget(self.scanperiodLabel,0,0)
        layout.addWidget(self.scanperiodSpinBox,0,1)
        layout.addWidget(self.isscanstackCheckBox,1,0)
        layout.addWidget(self.isautoscanCheckBox,2,0)
        #layout.addWidget(btn,3,0)

        self.optionsgbox.show()
        self.optionsgbox.setLayout(layout)
        
    def init_kmemleaks(self):
        self.kmemleak_kernel = '/sys/kernel/debug/kmemleak'

    def  showsteps(self,name):
        self.showstepsbox = QtGui.QGroupBox(name)
        layout = QtGui.QVBoxLayout()
        steps = """
=======================================================
0  CONFIG_DEBUG_KMEMLEAK in "Kernel hacking" 
   has to be enabled
   you can see :
   in file : kernel/.config
---CONFIG_DEBUG_KMEMLEAK=y
---CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400
---CONFIG_DEBUG_KMEMLEAK_TEST=y
---CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y

1  mount -t debugfs nodev /sys/kernel/debug/
2  cat /sys/kernel/debug/kmemleak
3  echo clear > /sys/kernel/debug/kmemleak
2  echo scan > /sys/kernel/debug/kmemleak
$$ more details you can refer:
     kernel/Documentation/kmemleak.txt
========================================================
""" 
        self.stepsLabel = QtGui.QLabel(steps)

        layout.addWidget(self.stepsLabel)

        self.showstepsbox.show()
        self.showstepsbox.setLayout(layout)
        
    def __init__(self, parent=None):

        super(KmemleakForm, self).__init__(parent)
        #self.frameStyle = QtGui.QFrame.Sunken | QtGui.QFrame.Panel
        self.setWindowTitle("kernel memleak")

        QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Plastique'))

        #self.normalbox , self.noramledit , self.normalbtn = self.showandroidProp('normal prop ')
        #self.refreshbtn = QtGui.QPushButton('refresh property')
        #self.connect(self.refreshbtn, SIGNAL('clicked()'), self.refreshProp)

        self.init_kmemleaks()
        self.showkmemleakoptions('kmemleak options :')
        self.showresults(' ------------- show   kmemleak   analyze   results ---------------')
        self.showsteps("find kernel memleak steps :")
        self.showcontrol('control kmemleak :')

        mainLayout = QGridLayout()
        mainLayoutleft = QGridLayout()
        mainLayoutleft.addWidget(self.showstepsbox,0,0)
        mainLayoutleft.addWidget(self.optionsgbox,1,0)
        mainLayoutleft.addWidget(self.controlgbox,2,0)
        mainLayout.addLayout(mainLayoutleft,0,0)
        mainLayout.addWidget(self.resultgbox,0,1)
        
        

        self.setLayout(mainLayout)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = None
    form = KmemleakForm()
    sys.exit(app.exec_())


